import Cell from "./cell.js"


// 画布配置
const configKonva = {
  width: document.documentElement.clientWidth,
  height: document.documentElement.clientHeight
}
//初始化画布宽高，适配移动端不同机型
if (configKonva.width >= 980) {
  configKonva.width = 500;
  configKonva.height = 500;
} else if (configKonva.width >= 650) {
  configKonva.width = 440;
  configKonva.height = 440;
} else {
  configKonva.width = 280;
  configKonva.height = 280;
}

// 背景rect
const bgRect = {
  x: 0,
  y: 0,
  width: configKonva['width'],
  height: configKonva['height'],
  fill: '#bbada0',
  stroke: '#bbada0',
  cornerRadius: 6
}

// 游戏管理类
function Game() {
  this.init()
}

// 初始化
Game.prototype.init = function () {
  this.vue = null

  this.score = 0 // 分数
  this.scs = '' // 加分器

  this.status = false // 游戏运行状态
  this.firstpass = false
  this.size = 4 // 4*4 大小
  this.startCells = 2 // 初始方块
  this.cells = [] // 方块
  this.sum = 0 // 有效方块总和

  this.configKonva = configKonva
  this.bgRect = bgRect
  // 加载块元素
  for (let row = 0; row < this.size; row++) {
    this.cells.push([])
    for (let col = 0; col < this.size; col++) {
      let cell = new Cell({
        col: col,
        row: row
      })
      this.cells[row].push(cell)
    }
  }
}

// 加分
Game.prototype.addScore = function (val) {
  this.score += val
  this.vue.score()
  this.scs = '+' + val
}
// 检查 是否无路可走
Game.prototype.check = function () {
  // 检查四周有无相同的值
  function checkCell(cells, row, col, size) {
    let cell = cells[row][col]
    for (let a of [
        [-1, 0],
        [1, 0],
        [0, -1],
        [0, 1]
      ]) {
      let r = a[0] + row,
        c = a[1] + col
      if (r < 0 || r >= size || c < 0 || c >= size) continue
      let scell = cells[r][c]
      if (cell.value == scell.value) return true
    }
    return false
  }
  if (this.sum == this.size * this.size) {
    // 堵满了 再判断能不能抢救下 不能就over了
    for (let row = 0; row < this.size; row++) {
      for (let col = 0; col < this.size; col++) {
        if (checkCell(this.cells, row, col, this.size)) return
      }
    }
    return this.gameover()
  }
}
// 生产个随机数 抽卡模拟器 2:85%  4:12%  8:3%
Game.prototype.getRandomValue = function () {
  let r = Math.random()
  if (r < .85) return 2
  else if (r < .97) return 4
  else if (r <= 1) return 8
}
// 生成一个方块
Game.prototype.addCell = function () {
  // 生成随机数 见缝插针
  let s = this.size * this.size - this.sum - 1
  let random = Math.round(Math.random() * s + 1)
  let i = 0
  for (let row = 0; row < this.size; row++) {
    for (let col = 0; col < this.size; col++) {
      if (this.cells[row][col].value != null) continue
      i++
      if (i == random) {
        let newValue = this.getRandomValue()
        this.cells[row][col].appear(newValue)
        this.sum += 1
        break
      }
    }
  }
  this.check()
}
// 移动函数
Game.prototype.move = function (cell, lastCell) {
  // 交换
  function exchange(cell, lastCell, cells) {
    let i = lastCell
    cells[p1.row][p1.col] = cell
    cells[p2.row][p2.col] = i
  }
  let p1 = JSON.parse(JSON.stringify({
    row: lastCell.row,
    col: lastCell.col
  }))
  let p2 = JSON.parse(JSON.stringify({
    row: cell.row,
    col: cell.col
  }))
  if (!lastCell.value) {
    // 目标为空 移过去
    cell.move(p1)
    lastCell.move(p2)
    exchange(cell, lastCell, this.cells)
  } else if (lastCell.value == cell.value) {
    // 目标协同 合并过去
    cell.move(p1)
    cell.setValue()
    lastCell.move(p2)
    lastCell.setValue(lastCell.value * 2)
    this.sum -= 1
    this.addScore(lastCell.value)
    exchange(cell, lastCell, this.cells)
    if (lastCell.value == 2048 && !this.firstpass) this.gamepass()
  }
}
// 移动上下左右 逻辑
Game.prototype.moveTop = function () {
  if (!this.status) return
  for (let r = 1; r < this.size; r++) {
    for (let c = 0; c < this.size; c++) {
      let cell = this.cells[r][c]
      if (!cell.value) continue
      // 循环 上移
      while (cell.row != 0) {
        let lastCell = this.cells[cell.row - 1][cell.col]
        this.move(cell, lastCell)
        cell = lastCell
      }
    }
  }
  this.addCell()
}
Game.prototype.moveBottom = function () {
  if (!this.status) return
  for (let r = this.size - 1; r >= 0; r--) {
    for (let c = 0; c < this.size; c++) {
      let cell = this.cells[r][c]
      if (!cell.value) continue
      // 循环 下移
      while (cell.row != this.size - 1) {
        let lastCell = this.cells[cell.row + 1][cell.col]
        this.move(cell, lastCell)
        cell = lastCell
      }
    }
  }
  this.addCell()
}
Game.prototype.moveLeft = function () {
  if (!this.status) return
  for (let r = 0; r < this.size; r++) {
    for (let c = 1; c < this.size; c++) {
      let cell = this.cells[r][c]
      if (!cell.value) continue
      // 循环 左移
      while (cell.col != 0) {
        let lastCell = this.cells[cell.row][cell.col - 1]
        this.move(cell, lastCell)
        cell = lastCell
      }
    }
  }
  this.addCell()
}
Game.prototype.moveRight = function () {
  if (!this.status) return
  for (let r = 0; r < this.size; r++) {
    for (let c = this.size - 1; c >= 0; c--) {
      let cell = this.cells[r][c]
      if (!cell.value) continue
      // 循环 右移
      while (cell.col != this.size - 1) {
        let lastCell = this.cells[cell.row][cell.col + 1]
        this.move(cell, lastCell)
        cell = lastCell
      }
    }
  }
  this.addCell()
}

// 游戏开始入口 - 重新开局
Game.prototype.start = function () {
  for (let row = 0; row < this.size; row++) {
    for (let col = 0; col < this.size; col++) {
      let cell = this.cells[row][col]
      cell.reset()
    }
  }
  this.sum = 0
  this.score = 0
  // 添加初始方块
  for (let i = 0; i < this.startCells; i++) {
    this.addCell()
  }
  this.status = true
}

// 游戏结束出口 - 失败
Game.prototype.gameover = function () {
  this.status = false
  setTimeout(() => {
    alert("你已无路可走！")
  }, 2000);
}
// 游戏结束出口 - 成功
Game.prototype.gamepass = function () {
  this.firstpass = true
  alert("你合成了2048，恭喜你过关了！")
}
export default Game